package com.frame.work.lib;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.frame.work.common.constant.RabbitTopic;
import com.frame.work.common.constant.RedisKey;
import com.frame.work.common.util.Frame;
import com.frame.work.entity.TblDevice;

import com.frame.work.entity.TblGroupDeviceRelation;
import com.frame.work.mapper.TblDeviceMapper;
import com.frame.work.mapper.TblGatewayMapper;
import com.frame.work.mapper.TblGroupMapper;
import com.frame.work.mqtt.Topic;
import com.frame.work.mqtt.data.handle.MqttDataHandle;
import com.frame.work.service.GroupDeviceRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author wjming
 */
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class GroupRespondHandle {
    private final GroupDeviceRelationService groupDeviceRelationService;
    private final TblDeviceMapper deviceMapper;
    private final MqttDataHandle mqttDataHandle;
    private final StringRedisTemplate stringRedisTemplate;
    private final RabbitTemplate rabbitTemplate;

    public void processFrame(String gatewayMac, String frameString) {
        log.info("[群组配置] -> [processFrame] -> [gatewayMac:{},数据帧:{}]", gatewayMac, frameString);
        String data = Frame.getData(frameString);
        String deal = StringUtils.substring(data, 18, 20);
        String randomCode = StringUtils.substring(data, 20, 24);
        if (deal.startsWith("8")) {
            Map<String, Object> rep = new HashMap<>();
            rep.put("type", "group");
            rep.put("code", StringUtils.substring(data, data.length() - 2, data.length()));
            rep.put("mode", deal);
            rep.put("gatewayMac", gatewayMac);
            //回应一下当前所配置的群组所处的情况
            mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group, JSONObject.toJSONString(rep));
        }

        if (deal.startsWith("0")) {
            switch (deal) {
                case "01":
                case "02":
                    moreDeviceDeal(data, gatewayMac, randomCode, deal);
                    break;
                case "03":
                    break;
                case "04":
                    //往数据库添加网关回应成功的设备信息
                    String redisValue4 = getRedisValue(RedisKey.deleteOneDeviceOnGroup(gatewayMac, randomCode));

                    String code4 = StringUtils.substring(data, data.length() - 2, data.length());
                    String deviceMac = StringUtils.substring(data, data.length() - 18, data.length() - 2);
                    String deviceId = deviceMapper.selectOne(Wrappers.<TblDevice>lambdaQuery()
                            .eq(TblDevice::getZigbeeMac, deviceMac)).getId();
                    if ("00".equals(code4)) {
                        boolean b = groupDeviceRelationService.removeById(redisValue4);
                        if (!b) {
                            System.out.println("删除失败");
                        }
                    }
                    List<TblGroupDeviceRelation> list = groupDeviceRelationService.list(Wrappers.<TblGroupDeviceRelation>lambdaQuery()
                            .eq(TblGroupDeviceRelation::getDeviceId, deviceId));
                    //查询此设备是否还有群组关系
                    if (list.size() < 1) {
                        Map<String, String> mqRemoveDeviceGroups = new HashMap<>(2);
                        mqRemoveDeviceGroups.put("deviceMac", deviceMac);
                        mqRemoveDeviceGroups.put("gatewayMac", gatewayMac);
                        rabbitTemplate.convertAndSend(RabbitTopic.deviceRemoveGroup, mqRemoveDeviceGroups);
                    }
                    Map<String, Object> repMap4 = new HashMap<>(32);
                    repMap4.put("type", "group/one/delete");
                    repMap4.put("zigbeeMac", deviceMac);
                    repMap4.put("relationId", redisValue4);
                    repMap4.put("mode", deal);
                    repMap4.put("code", code4);
                    repMap4.put("gatewayMac", gatewayMac);
                    mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + "/one/delete", JSONObject.toJSONString(repMap4));
                    break;
                case "05":
                    break;
                //清空某个设备的数据帧
                case "06":
                    String zigbeeMac = stringRedisTemplate.opsForValue().get(gatewayMac + "_" + randomCode);

                    if (StringUtils.isEmpty(zigbeeMac)) {
                        return;
                    }
                    stringRedisTemplate.delete(gatewayMac + "_" + randomCode);
                    String deviceMac06 = StringUtils.substring(data, data.length() - 18, data.length() - 2);
                    String code6 = StringUtils.substring(data, data.length() - 2, data.length());
                    Map<String, Object> repMap06 = new HashMap<>(5);
                    repMap06.put("type", "group/clear/all");
                    repMap06.put("zigbeeMac", zigbeeMac);
                    repMap06.put("mode", deal);
                    repMap06.put("code", code6);
                    repMap06.put("gatewayMac", gatewayMac);
                    TblDevice tblDevice = deviceMapper.selectOne(Wrappers.<TblDevice>lambdaQuery()
                            .eq(TblDevice::getZigbeeMac, zigbeeMac));
                    boolean remove = groupDeviceRelationService.remove(Wrappers.<TblGroupDeviceRelation>lambdaQuery()
                            .eq(TblGroupDeviceRelation::getDeviceId, tblDevice.getId()));
                    mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + "/clear/all", JSONObject.toJSONString(repMap06));
                    break;
                case "07":
                    //往数据库添加网关回应成功的设备信息
                    Map<String, Object> repMap7 = new HashMap<>(32);
                    String redisValueDeviceToGroup = getRedisValue(RedisKey.deviceAddMultipleGroup(gatewayMac, randomCode));
                    JSONArray deviceToGroupObjects = JSONObject.parseArray(redisValueDeviceToGroup);
                    String code = StringUtils.substring(data, data.length() - 2, data.length());
                    if ("00".equals(code)) {
                        List<TblGroupDeviceRelation> groupDeviceRelation7 = new ArrayList<>(32);
                        for (int i = 0; i < deviceToGroupObjects.size(); i++) {
                            Map<String, Object> map = (Map<String, Object>) deviceToGroupObjects.get(i);

                            int count = groupDeviceRelationService.count(Wrappers.<TblGroupDeviceRelation>lambdaQuery()
                                    .eq(TblGroupDeviceRelation::getGroupId, map.get("groupId"))
                                    .eq(TblGroupDeviceRelation::getDeviceId, map.get("deviceId")));
                            if (count == 0) {
                                TblGroupDeviceRelation tblGroupDeviceRelation = new TblGroupDeviceRelation();
                                tblGroupDeviceRelation.setGroupId((String) map.get("groupId"));
                                tblGroupDeviceRelation.setDeviceId((String) map.get("deviceId"));
                                groupDeviceRelation7.add(tblGroupDeviceRelation);
                            }

                        }
                        groupDeviceRelationService.saveBatch(groupDeviceRelation7);
                    }
                    repMap7.put("type", "group/device/update");
                    repMap7.put("zigbeeMac", StringUtils.substring(data, data.length() - 18, data.length() - 2));
                    repMap7.put("mode", deal);
                    repMap7.put("code", code);
                    repMap7.put("gatewayMac", gatewayMac);
                    mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + "/device" + Topic.groupMsg.update, JSONObject.toJSONString(repMap7));
                    break;
                default:
                    break;
            }


        }
    }


    private String getRedisValue(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }


    /**
     * 群组延时关命令处理
     *
     * @param gatewayMac
     * @param frame
     */
    public void delayTimeDeal(String gatewayMac, String frame) {
        log.info("[群组延时配置] -> [processFrame] -> [gatewayMac:{},数据帧:{}]", gatewayMac, frame);
        String data = Frame.getData(frame);
        String deal = StringUtils.substring(data, 18, 20);
        Map<String, Object> rep = new HashMap<>();
        rep.put("type", "group/delayTime");
        rep.put("code", StringUtils.substring(data, data.length() - 2, data.length()));
        rep.put("mode", deal);
        rep.put("gatewayMac", gatewayMac);
        //回应一下当前所配置的群组所处的情况
        mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + "/delayTime", JSONObject.toJSONString(rep));

    }


    private void moreDeviceDeal(String data, String gatewayMac, String randomCode, String deal) {
        //往数据库添加网关回应成功的设备信息
        String redisKey = "";
        String redisValue = "";

        if ("01".equals(deal)) {
            redisKey = RedisKey.groupAddMultipleDevices(gatewayMac, randomCode);
        }
        if ("02".equals(deal)) {
            redisKey = RedisKey.groupDeleteMultipleDevices(gatewayMac, randomCode);
        }
        redisValue = stringRedisTemplate.opsForValue().get(redisKey);
        JSONArray objects = JSONObject.parseArray(redisValue);
        List<Map<String, Object>> listIsFalse = new ArrayList<>(32);
        List<String> errorIds = new ArrayList<>(32);
        Map<String, Object> repMap = new HashMap<>(32);
        if ("01".equals(deal)) {
            repMap.put("type", "group/add");
        }
        if ("02".equals(deal)) {
            repMap.put("type", "group/delete");
        }

        repMap.put("mode", deal);
        repMap.put("deviceStatus", listIsFalse);
        repMap.put("gatewayMac", gatewayMac);
        //zigbeeMac截取
        if (!"00".equals(StringUtils.substring(data, 24, 26))) {
            List<String> errorMacList = new ArrayList<>(32);
            for (int i = 26; i < data.length() - 2; i = i + 18) {
                String zigbeeMacAndCode = StringUtils.substring(data, i, i + 18);
                String zigbeeMac = StringUtils.substring(zigbeeMacAndCode, 0, 16);
                String isFalse = StringUtils.substring(zigbeeMacAndCode, 16, 18);
                Map<String, Object> map = new HashMap<>();
                map.put("zigbeeMac", zigbeeMac);
                map.put("errorCode", isFalse);
                listIsFalse.add(map);
                errorMacList.add(zigbeeMac);
            }
            if (CollectionUtils.isNotEmpty(errorMacList)) {
                List<TblDevice> tblDevices = deviceMapper.selectList(Wrappers.<TblDevice>lambdaQuery().in(TblDevice::getZigbeeMac, errorMacList));
                List<String> deviceIds = tblDevices.stream().map(i -> i.getId()).collect(Collectors.toList());
                errorIds.addAll(deviceIds);
            }

        }

        List<TblGroupDeviceRelation> groupDeviceRelations = new ArrayList<>(32);
        for (int i = 0; i < objects.size(); i++) {
            boolean fa = true;
            TblGroupDeviceRelation tblGroupDeviceRelation = new TblGroupDeviceRelation();
            Map<String, Object> map = (Map<String, Object>) objects.get(i);
            String deviceId = (String) map.get("deviceId");
            String groupId = (String) map.get("groupId");
            for (String id : errorIds) {
                if (deviceId.equals(id)) {
                    fa = false;
                }
            }
            if (fa) {
                tblGroupDeviceRelation.setDeviceId(deviceId);
                tblGroupDeviceRelation.setGroupId(groupId);
                groupDeviceRelations.add(tblGroupDeviceRelation);
            }
        }

        if ("01".equals(deal)) {
            groupDeviceRelationService.saveBatch(groupDeviceRelations);
        }
        if ("02".equals(deal)) {
            for (TblGroupDeviceRelation groupDeviceRelation : groupDeviceRelations) {
                groupDeviceRelationService.remove(Wrappers.<TblGroupDeviceRelation>lambdaQuery()
                        .eq(TblGroupDeviceRelation::getDeviceId, groupDeviceRelation.getDeviceId())
                        .eq(TblGroupDeviceRelation::getGroupId, groupDeviceRelation.getGroupId()));
            }

        }


        if ("01".equals(deal)) {
            mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + Topic.groupMsg.add, JSONObject.toJSONString(repMap));
        }
        if ("02".equals(deal)) {
            mqttDataHandle.basePush(Topic.device.topics + gatewayMac + Topic.group + Topic.groupMsg.del, JSONObject.toJSONString(repMap));
        }
        //回应一下当前所配置的群组所处的情况

    }
}
